<!DOCTYPE html>


<html lang="en">


<head>
  <meta charset="utf-8" />
    
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
  <title>
     
  </title>
  <meta name="generator" content="hexo-theme-ayer">
  
  <link rel="shortcut icon" href="/favicon.ico" />
  
  
<link rel="stylesheet" href="/dist/main.css">

  
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/css/remixicon.min.css">

  
<link rel="stylesheet" href="/css/custom.css">

  
  
<script src="https://cdn.jsdelivr.net/npm/pace-js@1.0.2/pace.min.js"></script>

  
  

  

</head>

</html>

<body>
  <div id="app">
    
      
      <canvas width="1777" height="841"
        style="position: fixed; left: 0px; top: 0px; z-index: 99999; pointer-events: none;"></canvas>
      
    <main class="content on">
      
<section class="cover">
    
  <div class="cover-frame">
    <div class="bg-box">
      <img src="/images/82752296_p0.jpg" alt="image frame" />
    </div>
    <div class="cover-inner text-center text-white">
      <h1><a href="/">Doreen&#39;s Blog</a></h1>
      <div id="subtitle-box">
        
        <span id="subtitle"></span>
        
      </div>
      <div>
        
      </div>
    </div>
  </div>
  <div class="cover-learn-more">
    <a href="javascript:void(0)" class="anchor"><i class="ri-arrow-down-line"></i></a>
  </div>
</section>



<script src="https://cdn.jsdelivr.net/npm/typed.js@2.0.11/lib/typed.min.js"></script>


<!-- Subtitle -->

  <script>
    try {
      var typed = new Typed("#subtitle", {
        strings: ['一切都会好的，城南的花都开了', '今晚的月色真美', '注重过程，别在乎结果'],
        startDelay: 0,
        typeSpeed: 200,
        loop: true,
        backSpeed: 100,
        showCursor: true
      });
    } catch (err) {
      console.log(err)
    }
  </script>
  
<div id="main">
  <section class="outer">
  
  

<div class="notice" style="margin-top:50px">
    <i class="ri-heart-fill"></i>
    <div class="notice-content" id="broad"></div>
</div>
<script type="text/javascript">
    fetch('https://v1.hitokoto.cn')
        .then(response => response.json())
        .then(data => {
            document.getElementById("broad").innerHTML = data.hitokoto;
        })
        .catch(console.error)
</script>

<style>
    .notice {
        padding: 20px;
        border: 1px dashed #e6e6e6;
        color: #969696;
        position: relative;
        display: inline-block;
        width: 100%;
        background: #fbfbfb50;
        border-radius: 10px;
    }

    .notice i {
        float: left;
        color: #999;
        font-size: 16px;
        padding-right: 10px;
        vertical-align: middle;
        margin-top: -2px;
    }

    .notice-content {
        display: initial;
        vertical-align: middle;
    }
</style>
  
  <article class="articles">
    
    
    
    
    <article
  id="post-3d效果"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/14/3d%E6%95%88%E6%9E%9C/"
    >CSS实现3D效果</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/14/3d%E6%95%88%E6%9E%9C/" class="article-date">
  <time datetime="2020-01-14T07:16:00.000Z" itemprop="datePublished">2020-01-14</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/CSS/">CSS</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="transform相关属性实现3D效果"><a href="#transform相关属性实现3D效果" class="headerlink" title="transform相关属性实现3D效果"></a>transform相关属性实现3D效果</h2><style>
    ._3Dbox{
        width: 200px;
        margin: 200px auto;
        perspective: 2000px;    /* 视距 */
    }
    ._3Dbox .cube{
        position: relative;
        width: 200px;
        height: 200px;
        transform-style: preserve-3d;   /* 以3d的形式展示 ！！！ */
        animation: _3dmove 10s linear infinite;
    }
    ._3Dbox .cube div{
        position: absolute;
        width: 200px;
        height: 200px;
        border: 2px solid lightblue;
        line-height: 200px;
        font-size: 30px;
        opacity: 0.9;
        text-align: center;
        background: url('/images/avatar.jpg');
        background-size: contain;
    }
    ._3Dbox .cube div:nth-child(1){ /* 上 */
        transform:rotateX(90deg) translateZ(102px);
    }
    ._3Dbox .cube div:nth-child(2){ /* 下 */
        transform:rotateX(-90deg) translateZ(102px);
    }
    ._3Dbox .cube div:nth-child(3){ /* 前 */
        transform:translateZ(102px);
    }
    ._3Dbox .cube div:nth-child(4){ /* 后 */
        transform: translateZ(-102px);
    }
    ._3Dbox .cube div:nth-child(5){ /* 左 */
        transform: translateX(-102px) rotateY(90deg);
    }
    ._3Dbox .cube div:nth-child(6){ /* 右 */
        transform: translateX(102px) rotateY(-90deg);
    }
    @keyframes _3dmove {
        to{
            transform: rotateX(360deg) rotateY(360deg) ;
        }
    }

</style>
<div class="_3Dbox">
    <div class="cube">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
</div>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span>&#123;</span></span><br><span class="line">        width: 200px;</span><br><span class="line">        margin: 200px auto;</span><br><span class="line"><span class="css">        <span class="selector-tag">perspective</span>: 2000<span class="selector-tag">px</span>;    <span class="comment">/* 视距 */</span></span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span> <span class="selector-class">.cube</span>&#123;</span></span><br><span class="line">        position: relative;</span><br><span class="line">        width: 200px;</span><br><span class="line">        height: 200px;</span><br><span class="line"><span class="css">        <span class="selector-tag">transform-style</span>: <span class="selector-tag">preserve-3d</span>;   <span class="comment">/* 以3d的形式展示 ！！！ */</span></span></span><br><span class="line">        animation: _3dmove 10s linear infinite;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span>&#123;</span></span><br><span class="line">        position: absolute;</span><br><span class="line">        width: 200px;</span><br><span class="line">        height: 200px;</span><br><span class="line">        border: 2px solid lightblue;</span><br><span class="line">        line-height: 200px;</span><br><span class="line">        font-size: 30px;</span><br><span class="line"><span class="css">        <span class="selector-tag">opacity</span>: 0<span class="selector-class">.9</span>;</span></span><br><span class="line">        text-align: center;</span><br><span class="line">        background: url(&#x27;/images/avatar.jpg&#x27;);</span><br><span class="line">        background-size: contain;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(1)</span>&#123; <span class="comment">/* 上 */</span></span></span><br><span class="line"><span class="css">        <span class="selector-tag">transform</span><span class="selector-pseudo">:rotateX(90deg)</span> <span class="selector-tag">translateZ</span>(102<span class="selector-tag">px</span>);</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(2)</span>&#123; <span class="comment">/* 下 */</span></span></span><br><span class="line"><span class="css">        <span class="selector-tag">transform</span><span class="selector-pseudo">:rotateX(-90deg)</span> <span class="selector-tag">translateZ</span>(102<span class="selector-tag">px</span>);</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(3)</span>&#123; <span class="comment">/* 前 */</span></span></span><br><span class="line"><span class="css">        <span class="selector-tag">transform</span><span class="selector-pseudo">:translateZ(102px)</span>;</span></span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(4)</span>&#123; <span class="comment">/* 后 */</span></span></span><br><span class="line">        transform: translateZ(-102px);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(5)</span>&#123; <span class="comment">/* 左 */</span></span></span><br><span class="line">        transform: translateX(-102px) rotateY(90deg);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="selector-class">._3Dbox</span> <span class="selector-class">.cube</span> <span class="selector-tag">div</span><span class="selector-pseudo">:nth-child(6)</span>&#123; <span class="comment">/* 右 */</span></span></span><br><span class="line">        transform: translateX(102px) rotateY(-90deg);</span><br><span class="line">    &#125;</span><br><span class="line"><span class="css">    <span class="keyword">@keyframes</span> _3dmove &#123;</span></span><br><span class="line">        to&#123;</span><br><span class="line">            transform: rotateX(360deg) rotateY(360deg) ;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"><span class="tag">&lt;/<span class="name">style</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;_3Dbox&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">&quot;cube&quot;</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span>&gt;</span><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h2 id="CSS中的3D坐标轴"><a href="#CSS中的3D坐标轴" class="headerlink" title="CSS中的3D坐标轴"></a>CSS中的3D坐标轴</h2><blockquote>
<p>rotateX/Y/Z() 相当于绕X/Y/Z轴旋转 多少度<br>translateX/Y/Z() 相当于沿着X/Y/Z轴的方向移动多少像素  </p>
</blockquote>
<img src='/images/3d.webp' /> 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-迭代器模式"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/13/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F/"
    >【第七章】 迭代器模式</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/13/%E8%BF%AD%E4%BB%A3%E5%99%A8%E6%A8%A1%E5%BC%8F/" class="article-date">
  <time datetime="2020-01-13T07:16:00.000Z" itemprop="datePublished">2020-01-13</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="迭代器模式"><a href="#迭代器模式" class="headerlink" title="迭代器模式"></a>迭代器模式</h2><blockquote>
<p>提供一种 “顺序访问” 一个聚合对象中的各个元素，而又不需要暴露该对象的内部表示。<br>迭代模式可以把迭代的过程从业务逻辑中分离出来，在使用迭代器模式之后，即使不关心对象的内部构造，也可以按顺序方位其中的每个元素。</p>
</blockquote>
<p>自己实现一个迭代器：</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> each = <span class="function"><span class="keyword">function</span>(<span class="params">ary,callback</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;ary.length;i++)&#123;</span><br><span class="line">        callback.call(<span class="literal">null</span>,i,ary[i])   <span class="comment">// 把下标和元素当作参数传给callback函数</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">each([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],<span class="function"><span class="keyword">function</span>(<span class="params">i,n</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log([i,n])</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h2 id="内部迭代器"><a href="#内部迭代器" class="headerlink" title="内部迭代器"></a>内部迭代器</h2><blockquote>
<p>上面编写的 each 函数属于内部迭代器，each 函数的内部已经定义好了迭代规则，它完全接手整个迭代过程，外部只需要一次初始调用。  </p>
</blockquote>
<p>内部迭代器在调用的时候非常方便，外界不用关心迭代器内部的实现，跟迭代器的交互也仅仅是一次初始调用，但这也刚好是内部迭代器的缺点。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 内部迭代器实现 比较两个数组</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">compare</span>(<span class="params">ary1,ary2</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(ary1.length != ary2.length)&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;不相等&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    each(ary1,<span class="function"><span class="keyword">function</span>(<span class="params">i,n</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(ary2[i]!=n)&#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">&#x27;不相等&#x27;</span>) <span class="comment">// console.log(&#x27;不相等&#x27;)</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;相等&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line">compare([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>]) <span class="comment">// 相等</span></span><br></pre></td></tr></table></figure>

<h2 id="外部迭代器"><a href="#外部迭代器" class="headerlink" title="外部迭代器"></a>外部迭代器</h2><blockquote>
<p>外部迭代器必须显式地请求迭代下一个元素。<br>外部迭代器增加了一些调用的复杂度，但相对也增强了迭代器的灵活性，我们可以手工控制迭代的过程或者顺序。</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Iterator = <span class="function"><span class="keyword">function</span>(<span class="params">obj</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> current = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> next = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        current +=<span class="number">1</span>     </span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> isDone = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> current &gt;= obj.length</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> getCurrentItem = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> obj[current]</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        next: next,</span><br><span class="line">        isDone: isDone,</span><br><span class="line">        getCurrentItem: getCurrentItem</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 外部迭代器实现 比较两个数组</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">compare</span>(<span class="params">Iterator1,Iterator2</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(!Iterator1.isDone()&amp;&amp;!Iterator2.isDone())&#123;</span><br><span class="line">        <span class="keyword">if</span>(Iterator1.getCurrentItem() !== Iterator2.getCurrentItem())&#123;</span><br><span class="line">            <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">&#x27;不相等&#x27;</span>)</span><br><span class="line">        &#125;</span><br><span class="line">        Iterator1.next()</span><br><span class="line">        Iterator2.next()</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;相等&#x27;</span>)</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> Iterator1 = Iterator([<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>])</span><br><span class="line"><span class="keyword">var</span> Iterator2 = Iterator([<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>])</span><br><span class="line">compare(Iterator1,Iterator2)   <span class="comment">// 相等</span></span><br></pre></td></tr></table></figure>

<h2 id="迭代类数组对象和字面量对象"><a href="#迭代类数组对象和字面量对象" class="headerlink" title="迭代类数组对象和字面量对象"></a>迭代类数组对象和字面量对象</h2><blockquote>
<p>类数组：arguments<br>字面量对象：{‘0’:’a’,’1’:’b’}</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">each</span>(<span class="params">obj,callback</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> value,</span><br><span class="line">    i=<span class="number">0</span>,</span><br><span class="line">    length = obj.length,</span><br><span class="line">    isArray = isArraylike(obj); <span class="comment">//假装封装好了一个判断是否是类数组的方法</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span>(isArray)&#123;    <span class="comment">// 迭代类数组</span></span><br><span class="line">        <span class="keyword">for</span>(;i&lt;length;i++)&#123;</span><br><span class="line">            value = callback.call(<span class="literal">null</span>,i,obj[i])</span><br><span class="line">            <span class="keyword">if</span>(value === <span class="literal">false</span>)&#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        <span class="keyword">for</span>(i <span class="keyword">in</span> obj)&#123;</span><br><span class="line">            value = callback.call(<span class="literal">null</span>,i,obj[i])</span><br><span class="line">            <span class="keyword">if</span>(value === <span class="literal">false</span>)&#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> obj</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="中止迭代器"><a href="#中止迭代器" class="headerlink" title="中止迭代器"></a>中止迭代器</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> each = <span class="function"><span class="keyword">function</span>(<span class="params">ary,callback</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;ary.length;i++)&#123;</span><br><span class="line">        <span class="keyword">if</span>(callback(i,ary[i]) === <span class="literal">false</span>)&#123;</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">each([<span class="number">11</span>,<span class="number">21</span>,<span class="number">31</span>,<span class="number">41</span>,<span class="number">51</span>],<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(n&gt;<span class="number">30</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">console</span>.log(n)</span><br><span class="line">&#125;) <span class="comment">// 11 21</span></span><br></pre></td></tr></table></figure> 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-vue-element-admin权限管理&amp;动态路由配置"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/08/vue-element-admin%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86&%E5%8A%A8%E6%80%81%E8%B7%AF%E7%94%B1%E9%85%8D%E7%BD%AE/"
    >vue-element-admin权限管理&amp;动态路由配置</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/08/vue-element-admin%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86&%E5%8A%A8%E6%80%81%E8%B7%AF%E7%94%B1%E9%85%8D%E7%BD%AE/" class="article-date">
  <time datetime="2020-01-08T12:00:00.000Z" itemprop="datePublished">2020-01-08</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/vue/">vue</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <p><a target="_blank" rel="noopener" href="https://panjiachen.gitee.io/vue-element-admin-site/zh/guide/">vue-element-admin模板地址</a></p>
<blockquote>
<p>需求: 调用登陆接口之后 后台传递路由数据给前端 进行动态创建和显示  </p>
</blockquote>
<blockquote>
<p>问题: 各种问题 主要是不清楚这个模板的默认权限动态传递的配置</p>
</blockquote>
<h3 id="用到的核心文件地址"><a href="#用到的核心文件地址" class="headerlink" title="用到的核心文件地址"></a>用到的核心文件地址</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">src&#x2F;router&#x2F;index.js                     路由</span><br><span class="line">src&#x2F;store&#x2F;modules&#x2F;user.js               用户登录，用户信息、路由信息传递</span><br><span class="line">src&#x2F;permission.js                       信息传递（user -&gt; permission 的中间商）  之前就是一直没注意到这个 导致一直弄不好</span><br><span class="line">src&#x2F;store&#x2F;modules&#x2F;permission.js         权限获取&amp;配置</span><br></pre></td></tr></table></figure>
<h3 id="src-router-index-js-路由配置"><a href="#src-router-index-js-路由配置" class="headerlink" title="src/router/index.js 路由配置"></a>src/router/index.js 路由配置</h3><blockquote>
<p>constantRoutes: 不需要动态判断权限的路由 eg：登陆、404等通用页面<br>asyncRoutes：需要动态判断权限并通过addRoutes动态添加的页面  </p>
</blockquote>
<p>需要把动态路由先配置好 ‘permission’ 权限要写好<br>到时候才能正确的获取和显示相应的权限</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> constantRoutes = [</span><br><span class="line">  &#123;</span><br><span class="line">    path: <span class="string">&#x27;/login&#x27;</span>,</span><br><span class="line">    component: <span class="function">() =&gt;</span> <span class="keyword">import</span>(<span class="string">&#x27;@/views/login/index&#x27;</span>),</span><br><span class="line">    hidden: <span class="literal">true</span></span><br><span class="line">  &#125;,</span><br><span class="line">  &#123;</span><br><span class="line">    path: <span class="string">&#x27;/&#x27;</span>,</span><br><span class="line">    component: Layout,</span><br><span class="line">    redirect: <span class="string">&#x27;/dashboard&#x27;</span>,</span><br><span class="line">    children: [&#123;</span><br><span class="line">      path: <span class="string">&#x27;/dashboard&#x27;</span>,</span><br><span class="line">      name: <span class="string">&#x27;Dashboard&#x27;</span>,</span><br><span class="line">      component: <span class="function">() =&gt;</span> <span class="keyword">import</span>(<span class="string">&#x27;@/views/dashboard/index&#x27;</span>),</span><br><span class="line">      meta: &#123; <span class="attr">title</span>: <span class="string">&#x27;首页&#x27;</span>, <span class="attr">icon</span>: <span class="string">&#x27;dashboard&#x27;</span>, <span class="attr">affix</span>: <span class="literal">true</span> &#125;</span><br><span class="line">    &#125;]</span><br><span class="line">  &#125;</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> asyncRoutes = [</span><br><span class="line">  <span class="comment">//  待审核</span></span><br><span class="line">  &#123;</span><br><span class="line">    path: <span class="string">&#x27;/toPend&#x27;</span>,</span><br><span class="line">    component: Layout,</span><br><span class="line">    redirect: <span class="string">&#x27;/toPend&#x27;</span>,</span><br><span class="line">    permission: <span class="string">&#x27;toPend&#x27;</span>,</span><br><span class="line">    title: <span class="string">&#x27;待审核&#x27;</span>,</span><br><span class="line">    children: [</span><br><span class="line">      &#123;</span><br><span class="line">        permission: <span class="string">&#x27;toPend&#x27;</span>,</span><br><span class="line">        path: <span class="string">&#x27;/toPendIndex&#x27;</span>,</span><br><span class="line">        component: <span class="function">() =&gt;</span> <span class="keyword">import</span>(<span class="string">&#x27;@/views/toPendManagement/toPendIndex&#x27;</span>),</span><br><span class="line">        name: <span class="string">&#x27;toPend&#x27;</span>,</span><br><span class="line">        meta: &#123;</span><br><span class="line">          title: <span class="string">&#x27;待审核&#x27;</span>,</span><br><span class="line">          icon: <span class="string">&#x27;form&#x27;</span>,</span><br><span class="line">          noCache: <span class="literal">false</span> <span class="comment">// 如果设置为true，则不会被 &lt;keep-alive&gt; 缓存(默认 false)</span></span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    ]</span><br><span class="line">  &#125;,</span><br><span class="line">  ....</span><br><span class="line">  <span class="comment">// 404 page must be placed at the end !!!</span></span><br><span class="line">  &#123; <span class="attr">path</span>: <span class="string">&#x27;*&#x27;</span>, <span class="attr">redirect</span>: <span class="string">&#x27;/404&#x27;</span>, <span class="attr">hidden</span>: <span class="literal">true</span> &#125;</span><br><span class="line">]</span><br><span class="line"><span class="keyword">const</span> createRouter = <span class="function">() =&gt;</span> <span class="keyword">new</span> Router(&#123;</span><br><span class="line">  mode: <span class="string">&#x27;history&#x27;</span>, <span class="comment">// require service support</span></span><br><span class="line">  scrollBehavior: <span class="function">() =&gt;</span> (&#123; <span class="attr">y</span>: <span class="number">0</span> &#125;),</span><br><span class="line">  routes: constantRoutes</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> router = createRouter()</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="function"><span class="keyword">function</span> <span class="title">resetRouter</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> newRouter = createRouter()</span><br><span class="line">  router.matcher = newRouter.matcher <span class="comment">// reset router</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> router</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="src-store-modules-user-js-用户登陆获取数据"><a href="#src-store-modules-user-js-用户登陆获取数据" class="headerlink" title="src/store/modules/user.js 用户登陆获取数据"></a>src/store/modules/user.js 用户登陆获取数据</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">  正常流程是在login接口获取到 token，存在vuex中 供登陆</span></span><br><span class="line"><span class="comment">  然后在getInfo接口获取到 路由和用户信息 存储并发送出去 供路由的动态配置</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">  但是 我们这个项目把getInfo接口取消了 在login接口就直接获取到路由信息</span></span><br><span class="line"><span class="comment">  本来是不需要自己封装info数据的</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">const</span> actions = &#123;</span><br><span class="line">  <span class="comment">// user login</span></span><br><span class="line">  login(&#123;commit&#125;, userInfo) &#123;</span><br><span class="line">    <span class="keyword">const</span> &#123; username,password &#125; = userInfo</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">      login(&#123; <span class="attr">account</span>: username.trim(), <span class="attr">password</span>: password &#125;).then(<span class="function"><span class="params">response</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> &#123;</span><br><span class="line">          data</span><br><span class="line">        &#125; = response</span><br><span class="line">        <span class="comment">// 存储到cookie中 ！很重要 不然登陆不了 接口在 src/utils/auth.js</span></span><br><span class="line">        setToken(&#123; <span class="attr">username</span>: <span class="string">&#x27;admin&#x27;</span>, <span class="attr">password</span>: <span class="string">&#x27;admin&#x27;</span> &#125;)  </span><br><span class="line">        <span class="keyword">var</span> info = &#123; <span class="attr">username</span>: <span class="string">&#x27;admin&#x27;</span>, <span class="attr">password</span>: <span class="string">&#x27;admin&#x27;</span>, <span class="attr">roles</span>: [<span class="string">&#x27;admin&#x27;</span>], <span class="attr">routes</span>: data.permission &#125; </span><br><span class="line">         commit(<span class="string">&#x27;SET_TOKEN&#x27;</span>, info)  <span class="comment">// 存储到 vuex 中 数据格式如上 ↑ </span></span><br><span class="line">        resolve()</span><br><span class="line">      &#125;).catch(<span class="function"><span class="params">error</span> =&gt;</span> &#123;</span><br><span class="line">        reject(error)</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;,</span><br><span class="line">  getInfo(&#123; commit,state &#125;) &#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="comment">// 可以把这三个写在 info 中 从info里获取</span></span><br><span class="line">      <span class="keyword">const</span> roles = <span class="string">&#x27;admin&#x27;</span></span><br><span class="line">      <span class="keyword">const</span> name = <span class="string">&#x27;Super Admin&#x27;</span></span><br><span class="line">      <span class="keyword">const</span> avatar = <span class="string">&#x27;http://pic.51yuansu.com/pic3/cover/03/47/85/5badd30d6526d_610.jpg&#x27;</span></span><br><span class="line">      commit(<span class="string">&#x27;SET_ROLES&#x27;</span>, roles)</span><br><span class="line">      commit(<span class="string">&#x27;SET_NAME&#x27;</span>, name)</span><br><span class="line">      commit(<span class="string">&#x27;SET_AVATAR&#x27;</span>, avatar) <span class="comment">// 存储在cookie中</span></span><br><span class="line">      resolve(state.token)  <span class="comment">// 发送 info 值 ，传递给 permission</span></span><br><span class="line">     &#125;)</span><br><span class="line">  &#125;,</span><br><span class="line">  <span class="comment">// get user info 如果是有info接口的传递方法</span></span><br><span class="line">  <span class="comment">/* getInfo(&#123; commit, state &#125;) &#123;</span></span><br><span class="line"><span class="comment">    return new Promise((resolve, reject) =&gt; &#123;</span></span><br><span class="line"><span class="comment">      getInfo(state.token).then(response =&gt; &#123;</span></span><br><span class="line"><span class="comment">        const &#123; data &#125; = response</span></span><br><span class="line"><span class="comment">        if (!data) &#123;</span></span><br><span class="line"><span class="comment">          reject(&#x27;Verification failed, please Login again.&#x27;)</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        const &#123; roles, name, avatar &#125; = data</span></span><br><span class="line"><span class="comment">        // roles must be a non-empty array</span></span><br><span class="line"><span class="comment">        if (!roles || roles.length &lt;= 0) &#123;</span></span><br><span class="line"><span class="comment">          reject(&#x27;getInfo: roles must be a non-null array!&#x27;)</span></span><br><span class="line"><span class="comment">        &#125;</span></span><br><span class="line"><span class="comment">        commit(&#x27;SET_ROLES&#x27;, roles)</span></span><br><span class="line"><span class="comment">        commit(&#x27;SET_NAME&#x27;, name)</span></span><br><span class="line"><span class="comment">        commit(&#x27;SET_AVATAR&#x27;, avatar)</span></span><br><span class="line"><span class="comment">        console.log(data)</span></span><br><span class="line"><span class="comment">        resolve(data)</span></span><br><span class="line"><span class="comment">      &#125;).catch(error =&gt; &#123;</span></span><br><span class="line"><span class="comment">        reject(error)</span></span><br><span class="line"><span class="comment">      &#125;)</span></span><br><span class="line"><span class="comment">    &#125;)</span></span><br><span class="line"><span class="comment">  &#125;, */</span></span><br><span class="line">  ......</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> &#123;</span><br><span class="line">  namespaced: <span class="literal">true</span>,</span><br><span class="line">  state,</span><br><span class="line">  mutations,</span><br><span class="line">  actions</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="src-store-modules-permission-js-权限获取"><a href="#src-store-modules-permission-js-权限获取" class="headerlink" title="src/store/modules/permission.js 权限获取"></a>src/store/modules/permission.js 权限获取</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">  本来是根据角色roles权限过滤路由,并显示到侧边栏</span></span><br><span class="line"><span class="comment">  roles.</span></span><br><span class="line"><span class="comment">  但是现在是不根据权限 而是后台传递的路由信息 所以不用判断权限 修改为</span></span><br><span class="line"><span class="comment">  */</span></span><br><span class="line"><span class="keyword">const</span> actions = &#123;</span><br><span class="line">  generateRoutes(&#123; commit &#125;, userinfo) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="params">resolve</span> =&gt;</span> &#123;</span><br><span class="line">       <span class="keyword">const</span> strRoutes = <span class="built_in">JSON</span>.stringify(userinfo.routes)</span><br><span class="line">       <span class="keyword">const</span> accessedRoutes = filterAsyncRoutes(asyncRoutes, strRoutes) <span class="comment">//路由的过滤器 获取相同的路由</span></span><br><span class="line">      commit(<span class="string">&#x27;SET_ROUTES&#x27;</span>, accessedRoutes)</span><br><span class="line">      resolve(accessedRoutes)</span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="src-permission-js-用户信息传递-amp-配置路由"><a href="#src-permission-js-用户信息传递-amp-配置路由" class="headerlink" title="src/permission.js 用户信息传递&amp;配置路由"></a>src/permission.js 用户信息传递&amp;配置路由</h3><blockquote>
<p>首先确定userinfo需要的格式  就是getInfo函数传递过来的 resolve(state.token)</p>
</blockquote>
<p>path对应的是路由中的permission<br><img src='/images/数据格式.png' >  </p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">router.beforeEach(<span class="keyword">async</span>(to, <span class="keyword">from</span>, next) =&gt; &#123;</span><br><span class="line">  <span class="keyword">if</span> (hasToken) &#123;</span><br><span class="line">    <span class="keyword">if</span> (to.path === <span class="string">&#x27;/login&#x27;</span>) &#123;</span><br><span class="line">     ...</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// determine whether the user has obtained his permission roles through getInfo</span></span><br><span class="line">      <span class="keyword">const</span> hasRoles = store.getters.roles &amp;&amp; store.getters.roles.length &gt; <span class="number">0</span></span><br><span class="line">      <span class="keyword">if</span> (hasRoles) &#123;</span><br><span class="line">        next()</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// 登录后会走这里获取roles</span></span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">          <span class="comment">// get user info</span></span><br><span class="line">          <span class="comment">// note: roles must be a object array! such as: [&#x27;admin&#x27;] or ,[&#x27;developer&#x27;,&#x27;editor&#x27;]</span></span><br><span class="line">          <span class="keyword">const</span> userinfo = <span class="keyword">await</span> store.dispatch(<span class="string">&#x27;user/getInfo&#x27;</span>) <span class="comment">//获取用户信息</span></span><br><span class="line">          <span class="comment">// 调用store下module下的permission文件中的generateRoutes方法</span></span><br><span class="line">          <span class="keyword">const</span> accessRoutes = <span class="keyword">await</span> store.dispatch(<span class="string">&#x27;permission/generateRoutes&#x27;</span>, userinfo) <span class="comment">// 获取动态路由</span></span><br><span class="line">          <span class="comment">// dynamically add accessible routes 显示获取到的侧边栏</span></span><br><span class="line">          router.addRoutes(accessRoutes)  <span class="comment">//创建路由</span></span><br><span class="line"></span><br><span class="line">          next(&#123; ...to, <span class="attr">replace</span>: <span class="literal">true</span> &#125;)</span><br><span class="line">        &#125; <span class="keyword">catch</span> (error) &#123;</span><br><span class="line">          ...</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h3 id="被遗漏的BUG"><a href="#被遗漏的BUG" class="headerlink" title="被遗漏的BUG"></a>被遗漏的BUG</h3><blockquote>
<p>描述： 登录完成之后，进入操作页面 刷新 又需要重新登录  </p>
</blockquote>
<p>原因： 之前这个模板是调用的getInfo接口获取、存储路由信息<br>页面刷新之后 再次调用接口即可获取到路由等信息  </p>
<p>但是我们把getInfo接口废弃了 路由信息是登陆的时候获取<br>存在vuex中 在getInfo函数内直接使用的vuex存储的数据 并发布出去  </p>
<p><b style='color:red'>原因就在于 vuex刷新之后 数据就清空了！所以又需要重新登录 获取路由等信息。 </b>   </p>
<blockquote>
<p>解决:<br>在login登陆接口之后获取到路由数据<br>通过sessionStorage / localStorage 存放在本地<br>然后在使用 getInfo 函数的时候 不从vuex内获取 从 sessionStorage / localStorage 获取并发送    </p>
</blockquote>
<p>注意：在退出登陆的时候 即调用logout接口之前要通过.removeItem()进行删除操作 不然不能正常退出登陆</p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-await相关题目"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/08/await%E7%9B%B8%E5%85%B3%E9%A2%98%E7%9B%AE/"
    >事件循环相关-异步输出顺序问题</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/08/await%E7%9B%B8%E5%85%B3%E9%A2%98%E7%9B%AE/" class="article-date">
  <time datetime="2020-01-08T07:16:00.000Z" itemprop="datePublished">2020-01-08</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/JavaScript/">JavaScript</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="题目出处"><a href="#题目出处" class="headerlink" title="题目出处"></a><a target="_blank" rel="noopener" href="https://segmentfault.com/a/1190000016329715">题目出处</a></h2><blockquote>
<p>通过这个题目 大概搞懂了 async/await 的实际意义<br>也可以复习下事件循环机制</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">async1</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&quot;async1 start&quot;</span>);</span><br><span class="line">    <span class="keyword">await</span> async2();</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&quot;async1 end&quot;</span>);  <span class="comment">// 相当于async2这个promise对象的一个 .then()</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">async2</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">   <span class="built_in">console</span>.log(<span class="string">&quot;async2&quot;</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">&quot;script start&quot;</span>);  </span><br><span class="line"></span><br><span class="line"><span class="built_in">setTimeout</span>(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&quot;settimeout&quot;</span>);</span><br><span class="line">&#125;,<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">async1();   </span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span> (<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&quot;promise1&quot;</span>);   </span><br><span class="line">    resolve();</span><br><span class="line">&#125;).then(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&quot;promise2&quot;</span>);</span><br><span class="line">&#125;); </span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">&quot;script end&quot;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 整体同步的执行顺序</span></span><br><span class="line"><span class="comment"> * 1. console.log(&quot;script start&quot;)   -&gt; 输出 “ script start ”</span></span><br><span class="line"><span class="comment"> *  </span></span><br><span class="line"><span class="comment"> *  * setTimeout() 进入异步队列 *</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * 2. async1()  </span></span><br><span class="line"><span class="comment"> *      -&gt; 输出 “ async1 start ” </span></span><br><span class="line"><span class="comment"> *      -&gt; 进入 async2() 输出 “ async2 ”</span></span><br><span class="line"><span class="comment"> *      -&gt; await等待async2()函数返回一个promise实例 将 console.log(&#x27;async1 end&#x27;) 放入异步队列</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * 3. promise()</span></span><br><span class="line"><span class="comment"> *      -&gt; 输出 “ promise1 ” </span></span><br><span class="line"><span class="comment"> *      -&gt; resolve() 进入异步队列</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * 4. console.log(&quot;script end&quot;)   -&gt; 输出 “ script end ”</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * 异步队列：</span></span><br><span class="line"><span class="comment"> * setTimeout()               </span></span><br><span class="line"><span class="comment"> * console.log(&#x27;async1 end&#x27;)  </span></span><br><span class="line"><span class="comment"> * resolve()                  </span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment"> * 按宏 / 微任务 顺序输出</span></span><br><span class="line"><span class="comment"> * console.log(&#x27;async1 end&#x27;)  // 微任务 1  -&gt;   async1 end</span></span><br><span class="line"><span class="comment"> * resolve()                  // 微任务 2  -&gt;  promise2</span></span><br><span class="line"><span class="comment"> * setTimeout()               // 宏任务 1  -&gt;   settimeout</span></span><br><span class="line"><span class="comment"> * </span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>

<h2 id="async-await"><a href="#async-await" class="headerlink" title="async / await"></a>async / await</h2><blockquote>
<p>通过看起来是同步的代码来执行 async(异步) 操作。<br>await阻塞功能，相当于一个 .then()的功能，await后一般是跟的异步操作，加上之后 只有等他执行完之后，后面的代码才能进行<br>本质还是promise 属于微任务</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">asyncFunc</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">const</span> result = <span class="keyword">await</span> otherAsyncFunc();</span><br><span class="line">    <span class="built_in">console</span>.log(result);</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="comment">// 等价于:</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">asyncFunc</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> otherAsyncFunc().then(<span class="function"><span class="params">result</span> =&gt;</span> &#123;</span><br><span class="line">        <span class="built_in">console</span>.log(result);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="事件循环机制-EventLoop"><a href="#事件循环机制-EventLoop" class="headerlink" title="事件循环机制 (EventLoop)"></a>事件循环机制 (EventLoop)</h2><blockquote>
<p>JavaScript是单线程的 ( 所有在主线程执行 )<br>事件轮询机制：同步任务完成后，执行异步队列  </p>
</blockquote>
<p><b style='color:red'>单线程特点:</b>   </p>
<ol>
<li>代码从上至下以此执行  </li>
<li>同步（ 会阻塞后面代码的执行 ） &amp; 异步 ( 主线程同步任务之后触发执行 )  </li>
<li>同步代表：alert()  console.log()  赋值语句  </li>
<li>异步代表：定时器  事件的回调(  xx.onclick=function(){}  ) promise</li>
</ol>
<img src='/images/eventLoop.png'>

<p><b style='color:red'>事件循环:</b>  </p>
<ol>
<li>所有同步任务都在主线程上执行，形成一个执行栈</li>
<li>主线程之外，还存在一个”消息队列”。只要异步操作执行完成，就到消息队列中排队</li>
<li>一旦执行栈中的所有同步任务执行完毕，系统就会按次序读取消息队列中的异步任务，于是被读取的异步任务结束等待状态，进入执行栈，开始执行</li>
<li>主线程不断重复上面的第三步</li>
</ol>
<h2 id="宏任务和微任务"><a href="#宏任务和微任务" class="headerlink" title="宏任务和微任务"></a>宏任务和微任务</h2><blockquote>
<p>微任务和宏任务皆为异步任务，但是微任务的优先级高于宏任务。</p>
</blockquote>
<img src='/images/task.png'>
<img src='/images/tasks.png'> 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-options请求和axios跨域及cookie传递问题"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2020/01/01/options%E8%AF%B7%E6%B1%82%E5%92%8Caxios%E8%B7%A8%E5%9F%9F%E5%8F%8Acookie%E4%BC%A0%E9%80%92%E9%97%AE%E9%A2%98/"
    >options请求和axios跨域及cookie传递问题</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2020/01/01/options%E8%AF%B7%E6%B1%82%E5%92%8Caxios%E8%B7%A8%E5%9F%9F%E5%8F%8Acookie%E4%BC%A0%E9%80%92%E9%97%AE%E9%A2%98/" class="article-date">
  <time datetime="2020-01-01T02:00:00.000Z" itemprop="datePublished">2020-01-01</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/JavaScript/">JavaScript</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <blockquote>
<p>options请求： 检测请求的接口的信息（服务器接受的方法、跨域中测实际请求是否可以被服务器所接受）</p>
</blockquote>
<h3 id="什么情况下会发送options预检请求"><a href="#什么情况下会发送options预检请求" class="headerlink" title="什么情况下会发送options预检请求"></a>什么情况下会发送options预检请求</h3><blockquote>
<p>浏览器将CORS请求分为两类：简单请求、非简单请求</p>
</blockquote>
<ul>
<li><p>简单请求（不会发送预检请求）与非简单请求（请求之前发送options）的区别</p>
<ol>
<li><p>请求方法：get、post、head</p>
</li>
<li><p>http请求头信息：<br>accept<br>accept-language、<br>content-language、<br>content-type、<br>last-event-id  </p>
</li>
<li><p>content-type：<br>application/x-www-form-urlencoded、<br>multipart/form-data、<br>text/plain</p>
<blockquote>
<p>同时满足以上两个条件时，才是简单请求，否则为非简单请求</p>
</blockquote>
</li>
</ol>
</li>
</ul>
<h3 id="axios跨域并获取cookie"><a href="#axios跨域并获取cookie" class="headerlink" title="axios跨域并获取cookie"></a>axios跨域并获取cookie</h3><p>  <a target="_blank" rel="noopener" href="http://www.axios-js.com/zh-cn/docs/">axios详细配置文档</a></p>
<blockquote>
<p>核心：<br>1.axios全局配置中添加  withCredentials: true 跨域并保存cookie<br>2.在请求拦截器内设置 content-type：application/json  </p>
</blockquote>
<p>  不是很理解第二点 加了之后不是把所有请求都变成非简单请求了吗<br>  但是不加的话就报错了<br>  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> axios <span class="keyword">from</span> <span class="string">&#x27;axios&#x27;</span></span><br><span class="line"><span class="keyword">import</span> &#123; MessageBox, Message &#125; <span class="keyword">from</span> <span class="string">&#x27;element-ui&#x27;</span></span><br><span class="line"><span class="keyword">import</span> store <span class="keyword">from</span> <span class="string">&#x27;@/store&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// create an axios instance</span></span><br><span class="line">axios.defaults.headers.common[<span class="string">&#x27;X-Requested-With&#x27;</span>] = <span class="string">&#x27;XMLHttpRequest&#x27;</span> <span class="comment">// ！ 可能是非必须 </span></span><br><span class="line">  <span class="keyword">const</span> service = axios.create(&#123;</span><br><span class="line">  baseURL: process.env.VUE_APP_BASE_API, <span class="comment">// url = base url + request url</span></span><br><span class="line">  withCredentials: <span class="literal">true</span>, <span class="comment">// send cookies when cross-domain requests</span></span><br><span class="line">  timeout: <span class="number">5000</span> <span class="comment">// request timeout</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="comment">// request interceptor 请求拦截</span></span><br><span class="line">service.interceptors.request.use(</span><br><span class="line">  config =&gt; &#123;</span><br><span class="line">    config.headers = &#123;</span><br><span class="line">      <span class="string">&#x27;Content-Type&#x27;</span>: <span class="string">&#x27;application/json&#x27;</span> <span class="comment">//  注意：设置很关键</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> config</span><br><span class="line">  &#125;,</span><br><span class="line">  error =&gt; &#123;</span><br><span class="line">    <span class="comment">// do something with request error</span></span><br><span class="line">    <span class="built_in">console</span>.log(error) <span class="comment">// for debug</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">Promise</span>.reject(error)</span><br><span class="line">  &#125;</span><br><span class="line">)</span><br></pre></td></tr></table></figure></p>
<p>  后端相应的配置：<br>  <figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">response.setHeader(<span class="string">&#x27;Access-Control-Allow-Credentials&#x27;</span>,<span class="keyword">true</span>); <span class="comment">// 必须加上</span></span><br><span class="line">response.setHeader(<span class="string">&#x27;Access-Control-Allow-Origin&#x27;</span>,<span class="string">&#x27;http://localhost:9528&#x27;</span>);   <span class="comment">//不能写成 * ，一定要指定地址</span></span><br><span class="line">response.setHeader(<span class="string">&#x27;Set-Cookie&#x27;</span>,<span class="string">&#x27;token=cowshield&#x27;</span>); <span class="comment">//传递的数据</span></span><br></pre></td></tr></table></figure></p>
<h3 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h3><p>  按理说应该是可以了<br>  但是后台说因为有options预检请求<br>  所以请求会有两次 但是他能获取的是options那次 后面那个请求获取不到<br>  但是options请求又没有能保存传递的数据 导致一些问题  </p>
<h3 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h3><p>  我觉得不严谨 但是有效<br>  大概是 写了一个拦截器 对于options请求直接返回true 就可以进入下一个请求了  </p>
<h3 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h3><p>  <a target="_blank" rel="noopener" href="http://www.ruanyifeng.com/blog/2016/04/cors.html">http://www.ruanyifeng.com/blog/2016/04/cors.html</a><br>  <a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_25551573/article/details/80690583">https://blog.csdn.net/qq_25551573/article/details/80690583</a></p>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-2019年总结"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/12/31/2019%E5%B9%B4%E6%80%BB%E7%BB%93/"
    >2019年度总结</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2019/12/31/2019%E5%B9%B4%E6%80%BB%E7%BB%93/" class="article-date">
  <time datetime="2019-12-31T02:21:42.000Z" itemprop="datePublished">2019-12-31</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E6%97%A5%E5%B8%B8/">日常</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <pre>
关键词：忙碌、压抑

今年可以说是压力最大的一年  比我高考压力还大
上半年基本一直在学前端相关的东西 积累项目经验
刚好在项目实训的时候也用上了 之前一直操心的实训算是轻松顺利完成

下半年一直在准备秋招相关的东西  边面试边查漏补缺
这两个学期我和考研党一样 早出晚归 基本天天呆在教室

秋招这几个月 是我迄今为止度过的最黑暗的日子
激动，希望，失望，自我怀疑，放弃 各种感情都经历过了
但也好在自己的坚持和努力 在秋招快结束的时候稀里糊涂的找了一份对我来说还不错的工作（七月份过了体检才能正式入职，感觉还是没底）
毕设这边虽然中途出现了一个小bug，但也解决了，开题也挺顺利的 希望明年能顺利毕业

十一月底学校的事情处理完，三方流程走完就马不停蹄的找了份实习
一个人拖着行李来到长沙 
目前是我实习刚好一个月，和我想象的不太一样，
干满三个月就不想干了，感觉在浪费时间，没有我自学学的多

大学生活也差不多快结束了 
讲真这段日子没什么可以留恋的
简直是糟透了的日子
唯一教会我的是如何习惯孤独
以前连上厕所都要拉着人去的我
现在已经习惯一个人吃饭，上课，自习，逛超市。。。

有时想想也觉得自己挺可怜的
不知道从什么时候开始  我好像也成了别人眼中的异类
我也不是不合群啊 只是好像适应不了这种快节奏的交友模式
不知道怎么融入 也没有机会融入

行吧 也不奢求太多
只希望2020年 工作和学习能顺顺利利
我可能没有那么强大的内心再来一次了
</pre>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-CSS相关"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/12/30/CSS%E7%9B%B8%E5%85%B3/"
    >CSS相关</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2019/12/30/CSS%E7%9B%B8%E5%85%B3/" class="article-date">
  <time datetime="2019-12-30T02:21:42.000Z" itemprop="datePublished">2019-12-30</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/CSS/">CSS</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <blockquote>
<p>想闲暇的时候学点CSS动画的实现方法，<br>希望能持续更新 见证自己的成长 ，实现的效果也能越来越复杂好看！</p>
</blockquote>
<h1 id="波纹效果"><a href="#波纹效果" class="headerlink" title="波纹效果"></a>波纹效果</h1><iframe id="cp_embed_VwYEwme" src="//codepen.io/曾zZ/embed/VwYEwme?height=500]&theme-id=dark&slug-hash=VwYEwme&default-tab=[" scrolling="no" frameborder="no" height="500]" allowTransparency="true" allowfullscreen="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;"></iframe>

<h1 id="充电动画"><a href="#充电动画" class="headerlink" title="充电动画"></a>充电动画</h1><blockquote>
<p>核心原理 filter的两个属性 blur（高斯模糊）px、contrast（对比度）%、hue-rotate(色相旋转) deg<br>有个疑问 就是w3c里面查的contrast的单位应该是 % 这个例子里面如果给它加了单位就实现不了了 就直接改变整体的对比度<br>blur(px): 默认为0，数值越大越模糊<br>contrast(%): 0%全黑，100%图像无变化。默认为1，超过100%图像会比原来亮<br>hue-rotate(deg)：0deg图像无变化。默认是0deg。该值虽然没有最大值，超过360deg的值相当于又绕一圈。<br><b style='color:red'>Tips:<br>背景一般选择黑色或者白色，不然会受到contrast和hue-rotate的影响<br>在实现渐变效果的时候 filter: contrast(20) hue-rotate(0deg); 顺序不能变<br></b></p>
</blockquote>
<style>
  /*外层盒子不设置 对比度*/
  .css-box .test,.test1,.test2,.test3{
    width: 100px;
    height: 100px;
    background: black;
    position: relative;
  }
  .css-box .test::before {
    content: " ";
    width: 50px;
    height: 50px;
    filter: blur(15px);
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    background: white;
    position: absolute;
  }
  /*外层盒子设置 对比度*/
  .css-box .test1 { 
    filter: contrast(20);
  }
  .css-box .test1::before {
    content: " ";
    width: 50px;
    height: 50px;
    filter: blur(15px);
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    margin: auto;
    background: white;
    position: absolute;
  }
  /* 内部盒子相遇时*/
  .css-box .test2 {
    filter: contrast(20);
  }
  .css-box .test2::before {
    content: " ";
    width: 50px;
    height: 50px;
    filter: blur(5px);
    left: 50%;
    top: 50%;
    border-radius: 50%;
    margin-left: -25px;
    margin-top: -25px;
    background: white;
    position: absolute;
  }
  .css-box .test2::after {
    content: " ";
    width: 20px;
    height: 20px;
    border-radius: 50%;
    filter: blur(5px);
    left: 50%;
    top: 50%;
    margin-left: -40px;
    margin-top: -10px;
    background: red;
    position: absolute;
  }
  /*内部盒子运动+渐变颜色*/
  /* filter: contrast(20) hue-rotate(0deg); 顺序不能变*/
  .css-box .test3 {
    filter: contrast(20) hue-rotate(0deg);
    animation: changeColor 5s linear infinite
  }
  @keyframes changeColor {
    100% {
      filter: contrast(20) hue-rotate(360deg);
    }
  }
  .css-box .test3::before {
    content: " ";
    width: 50px;
    height: 50px;
    filter: blur(5px);
    left: 50%;
    top: 50%;
    border-radius: 50%;
    margin-left: -25px;
    margin-top: -25px;
    background: rgb(201, 93, 93);
    position: absolute;
    animation: bigBallMove 2s linear infinite
  }
  .css-box .test3::after {
    content: " ";
    width: 20px;
    height: 20px;
    border-radius: 50%;
    filter: blur(5px);
    left: 50%;
    top: 50%;
    margin-left: -40px;
    margin-top: -10px;
    background: rgb(201, 93, 93);
    position: absolute;
    animation: ballMove 2s linear infinite;
  }
  @keyframes ballMove {
    100% {
      transform: translateX(70px);
    }
  }
  @keyframes bigBallMove {
    100% {
      transform: translateX(-20px);
    }
  }
  .css-box{
    width: 200px;
    height: 200px;
    border: 1px solid #ccc;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
  }
</style>

  <div class="css-box">
    内部设置高斯模糊 外层盒子不设置 对比度
    <div class="test"></div>
  </div>
  <div class="css-box">
    外层盒子设置 对比度 <br>
    （好像是在视觉上抵消内部盒子的高斯模糊）
    <div class="test1"></div>
  </div>
  <div class="css-box">
    内部盒子相遇时
    <div class="test2"></div>
  </div>
  <div class="css-box">
    内部盒子运动+渐变颜色<br>
    （filter: contrast(20) hue-rotate(0deg); 顺序不能变！！！）
    <div class="test3"></div>
  </div>

<p>  成品效果：</p>
  <iframe id="cp_embed_oNgaNLg" src="//codepen.io/曾zZ/embed/oNgaNLg?height=500]&theme-id=dark&slug-hash=oNgaNLg&default-tab=[" scrolling="no" frameborder="no" height="500]" allowTransparency="true" allowfullscreen="true" class="cp_embed_iframe" style="width: 100%; overflow: hidden;"></iframe>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-第六章__代理模式"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/12/28/%E7%AC%AC%E5%85%AD%E7%AB%A0__%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/"
    >【第六章】代理模式</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2019/12/28/%E7%AC%AC%E5%85%AD%E7%AB%A0__%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/" class="article-date">
  <time datetime="2019-12-28T15:00:00.000Z" itemprop="datePublished">2019-12-28</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <blockquote>
<p>定义: 为一个对象提供一个代用品或占位符，以控制对它的访问<br>关键：当客户不方便直接访问一个对象或者不满足需求的时候，提供一个替身对象来控制对这个对象的访问，客户实际上访问的是替身对象。替身对象对请求作出一些处理之后，再把请求转交给本体对象  </p>
</blockquote>
<p>不使用代理模式：  客户 ——&gt;  本体<br>使用代理模式：    客户 ——&gt;  代理  ——&gt;  本体</p>
<h2 id="一个解释代理模式的例子"><a href="#一个解释代理模式的例子" class="headerlink" title="一个解释代理模式的例子"></a>一个解释代理模式的例子</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">M  直接送花给 A</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">var</span> Flower = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;</span><br><span class="line"><span class="keyword">var</span> M = &#123;</span><br><span class="line">    sendFlower: <span class="function"><span class="keyword">function</span>(<span class="params">target</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> flower = <span class="keyword">new</span> Flower()</span><br><span class="line">        target.receiveFlower(flower)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> A = &#123;</span><br><span class="line">    receiveFlower: <span class="function"><span class="keyword">function</span>(<span class="params">flower</span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;收到花&#x27;</span>+flower)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">M.sendFlower(A)</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">M 通过 B 送花给 A</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">var</span> Flower = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;</span><br><span class="line"><span class="keyword">var</span> M = &#123;</span><br><span class="line">    sendFlower: <span class="function"><span class="keyword">function</span>(<span class="params">target</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> flower = <span class="keyword">new</span> Flower()</span><br><span class="line">        target.receiveFlower(flower)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> B = &#123;</span><br><span class="line">    receiveFlower: <span class="function"><span class="keyword">function</span>(<span class="params">flower</span>)</span>&#123;</span><br><span class="line">        A.receiveFlower(flower)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> A = &#123;</span><br><span class="line">    receiveFlower: <span class="function"><span class="keyword">function</span>(<span class="params">flower</span>)</span>&#123;</span><br><span class="line">        <span class="built_in">console</span>.log(<span class="string">&#x27;收到花&#x27;</span>+flower)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">M.sendFlower(B)</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">现在我们改变故事的背景设定，假设当 A 在心情好的时候收到花，小明表白成功的几率有60%，而当 A 在心情差的时候收到花，小明表白的成功率无限趋近于 0。</span></span><br><span class="line"><span class="comment">小明跟 A 刚刚认识两天，还无法辨别 A 什么时候心情好。如果不合时宜地把花送给 A，花被直接扔掉的可能性很大</span></span><br><span class="line"><span class="comment">但是 A 的朋友 B 却很了解 A，所以小明只管把花交给 B，B 会监听 A 的心情变化，然后选择 A 心情好的时候把花转交给 A，</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">var</span> Flower = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line"><span class="keyword">var</span> M = &#123;</span><br><span class="line">sendFlower: <span class="function"><span class="keyword">function</span> (<span class="params">target</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> flower = <span class="keyword">new</span> Flower()</span><br><span class="line">    target.receiveFlower(flower)</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> B = &#123;</span><br><span class="line">receiveFlower: <span class="function"><span class="keyword">function</span> (<span class="params">flow</span>) </span>&#123;</span><br><span class="line">    A.hasGoodMood(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    A.receiveFlower(flow)</span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> A = &#123;</span><br><span class="line">receiveFlower: <span class="function"><span class="keyword">function</span> (<span class="params">flow</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;get flower&#x27;</span> + flow)</span><br><span class="line">&#125;,</span><br><span class="line">hasGoodMood: <span class="function"><span class="keyword">function</span>(<span class="params">fn</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">    fn()</span><br><span class="line">    &#125;, <span class="number">1000</span>);</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">M.sendFlower(B)</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<h2 id="保护代理和虚拟代理"><a href="#保护代理和虚拟代理" class="headerlink" title="保护代理和虚拟代理"></a>保护代理和虚拟代理</h2><blockquote>
<p>代理B可以帮助A过滤掉一些请求的叫做保护代理 (通过B来控制对A的访问)<br>代理 B 会选择在 A 心情好时再执行 new Flower叫作虚拟代理。 (虚拟代理把一些开销很大的对象，延迟到真正需要它的时候才去创建)</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> B = &#123;</span><br><span class="line">    receiveFlower: <span class="function"><span class="keyword">function</span>(<span class="params">flower</span>)</span>&#123;</span><br><span class="line">        A.listenGoodMood(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;    <span class="comment">//监听A的好心情</span></span><br><span class="line">            <span class="keyword">var</span> flower = <span class="keyword">new</span> Flower() <span class="comment">//延迟创建flower对象</span></span><br><span class="line">            A.receiveFlower(flower)</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="虚拟代理实现图片预加载"><a href="#虚拟代理实现图片预加载" class="headerlink" title="虚拟代理实现图片预加载"></a>虚拟代理实现图片预加载</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">var</span> oImg = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> imgNode = <span class="built_in">document</span>.createElement(<span class="string">&#x27;img&#x27;</span>)</span><br><span class="line">    <span class="built_in">document</span>.body.appendChild(imgNode)</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        setSrc : <span class="function"><span class="keyword">function</span>(<span class="params">src</span>)</span>&#123;</span><br><span class="line">            imgNode.src = src</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)()</span><br><span class="line"></span><br><span class="line"><span class="comment">//代理对象</span></span><br><span class="line"><span class="keyword">var</span> proxyImage = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> img = <span class="keyword">new</span> Image()   <span class="comment">//获取的img对象</span></span><br><span class="line">    img.onload = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        oImg.setSrc(<span class="built_in">this</span>.src)   <span class="comment">//img.src</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        setSrc: <span class="function"><span class="keyword">function</span>(<span class="params">src</span>)</span>&#123;</span><br><span class="line">            oImg.setSrc(<span class="string">&#x27;./loading.gif&#x27;</span>)</span><br><span class="line">            img.src = src</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)()</span><br><span class="line">proxyImage.setSrc(<span class="string">&#x27;http://....jpg&#x27;</span>)</span><br></pre></td></tr></table></figure>

<h2 id="代理的意义"><a href="#代理的意义" class="headerlink" title="代理的意义"></a>代理的意义</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//不使用代理的方式</span></span><br><span class="line"><span class="keyword">var</span> oImg = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> imgNode = <span class="built_in">document</span>.createElement(<span class="string">&#x27;img&#x27;</span>)</span><br><span class="line">    <span class="built_in">document</span>.body.appendChild(imgNode)</span><br><span class="line">    <span class="keyword">var</span> img = <span class="keyword">new</span> Image</span><br><span class="line">    img.onload = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        imgNode.src = img.src</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">        setSrc : <span class="function"><span class="keyword">function</span>(<span class="params">src</span>)</span>&#123;</span><br><span class="line">            imgNode.src = <span class="string">&#x27;./timg.jpg&#x27;</span></span><br><span class="line">            img.src = src</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)()</span><br><span class="line">oImg.setSrc(<span class="string">&#x27;https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=629448732,2965351611&amp;fm=15&amp;gp=0.jpg&#x27;</span>)</span><br><span class="line">    </span><br></pre></td></tr></table></figure>
<p>单一职责原则：为了减少代码的耦合性，方便维护和修改</p>
<h2 id="代理和本体接口的一致性"><a href="#代理和本体接口的一致性" class="headerlink" title="代理和本体接口的一致性"></a>代理和本体接口的一致性</h2><blockquote>
<p>调用时的代理接口和本地接口名称一致 也通过直接返回函数  </p>
</blockquote>
<p><b style='color:red'>优点：</b></p>
<ol>
<li>用户可以放心地请求代理，他只关心是否能得到想要的结构</li>
<li>在任何使用本体的地方都可以替换成使用代理<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myImage = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> imgNode = <span class="built_in">document</span>.createElement(<span class="string">&#x27;img&#x27;</span>)</span><br><span class="line">    <span class="built_in">document</span>.appendChild(imgNode)</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">src</span>)</span>&#123;</span><br><span class="line">        imgNode.src = src</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)()</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> proxyImage = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> img = <span class="keyword">new</span> Image</span><br><span class="line">    img.onload = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        myImage( <span class="built_in">this</span>.src )</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">src</span>)</span>&#123;</span><br><span class="line">        myImage(<span class="string">&#x27;./timg.jpg&#x27;</span>)</span><br><span class="line">        img.src = src</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)()</span><br><span class="line">proxyImage(<span class="string">&#x27;https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=629448732,2965351611&amp;fm=15&amp;gp=0.jpg&#x27;</span>)</span><br></pre></td></tr></table></figure>
</li>
</ol>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-第五章__策略模式"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/12/28/%E7%AC%AC%E4%BA%94%E7%AB%A0__%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F/"
    >【第五章】策略模式</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2019/12/28/%E7%AC%AC%E4%BA%94%E7%AB%A0__%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F/" class="article-date">
  <time datetime="2019-12-28T02:21:42.000Z" itemprop="datePublished">2019-12-28</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <h2 id="策略模式"><a href="#策略模式" class="headerlink" title="策略模式"></a>策略模式</h2><p>比如要实现某一个功能有多种方案可以选择。比如压缩文件的程序，既可以选择zip算法，也可以选择gzip算法</p>
<blockquote>
<p>定义： 定义一系列的算法，把它们一个个封装起来，并且使它们可以相互替换</p>
</blockquote>
<ul>
<li><p>策略模式的优缺点<br>  <b style='color:Red'>优点：</b></p>
<pre><code>  1. 策略模式利用组合、委托和多态等技术和思想，可以有效地避免多重条件选择语句。
  2. 策略模式提供了对开放—封闭原则的完美支持，将算法封装在独立的 strategy 中，使得它们易于切换，易于理解，易于扩展。
  3. 策略模式中的算法也可以复用在系统的其他地方，从而避免许多重复的复制粘贴工作。
  4. 在策略模式中利用组合和委托来让 Context 拥有执行算法的能力，这也是继承的一种更轻便的替代方案。</code></pre>
<p>  <b style='color:Red'>缺点：</b></p>
<pre><code>  1. 使用策略模式会在程序中增加许多策略类或者策略对象，但实际上这比把它们负责的逻辑堆砌在 Context 中要好
  2. 要使用策略模式，必须了解所有的 strategy，必须了解各个 strategy 之间的不同点，这样才能选择一个合适的 strategy。</code></pre>
<ul>
<li><p>使用策略模式计算奖金</p>
  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">绩效为 S 的人年终奖有 4 倍工资，绩效为 A 的人年终奖有 3 倍工资，而绩效为 B 的人年终奖是 2 倍工资。假设财务部要求我们提供一段代码，来方便他们计算员工的年终奖</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//最初代码实现</span></span><br><span class="line"><span class="keyword">var</span> calculateBonus = <span class="function"><span class="keyword">function</span>(<span class="params">performanceLevel,salary</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(performanceLevel === <span class="string">&#x27;S&#x27;</span>)<span class="keyword">return</span> salary*<span class="number">4</span></span><br><span class="line">    <span class="keyword">if</span>(performanceLevel === <span class="string">&#x27;A&#x27;</span>)<span class="keyword">return</span> salary*<span class="number">3</span></span><br><span class="line">    <span class="keyword">if</span>(performanceLevel === <span class="string">&#x27;B&#x27;</span>)<span class="keyword">return</span> salary*<span class="number">2</span></span><br><span class="line">&#125;</span><br><span class="line">caculateBonus(<span class="string">&#x27;B&#x27;</span>,<span class="number">2000</span>) <span class="comment">//输出 4000</span></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">缺点：</span></span><br><span class="line"><span class="comment">1. calculateBonus 函数比较庞大，包含了很多 if-else 语句，这些语句需要覆盖所有的逻辑分支。</span></span><br><span class="line"><span class="comment">2. calculateBonus 函数缺乏弹性，如果增加了一种新的绩效等级 C，或者想把绩效 S 的奖金系数改为 5，那我们必须深入 calculateBonus 函数的内部实现，这是违反开放-封闭原则的。</span></span><br><span class="line"><span class="comment">3. 算法的复用性差，如果在程序的其他地方需要重用这些计算奖金的算法呢？我们的选择只有复制和粘贴。</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//使用策略模式重构代码</span></span><br><span class="line"><span class="comment">//目的： 算法的使用与算法的实现分离</span></span><br><span class="line"><span class="keyword">var</span> perfromanceS = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;</span><br><span class="line">perfromanceS.prototype.calculate = <span class="function"><span class="keyword">function</span>(<span class="params"> salary </span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> salary*<span class="number">4</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> perfromanceA = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;</span><br><span class="line">perfromanceA.prototype.calculate = <span class="function"><span class="keyword">function</span>(<span class="params"> salary </span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> salary*<span class="number">3</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> perfromanceB = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;</span><br><span class="line">perfromanceB.prototype.calculate = <span class="function"><span class="keyword">function</span>(<span class="params"> salary </span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> salary*<span class="number">2</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//奖金类</span></span><br><span class="line"><span class="keyword">var</span> Bonus = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.salary = <span class="literal">null</span>      <span class="comment">//原始工资</span></span><br><span class="line">    <span class="built_in">this</span>.strategy = <span class="literal">null</span>       <span class="comment">//绩效等级对应的策略对象</span></span><br><span class="line">&#125;</span><br><span class="line">Bonus.prototype.setSalary = <span class="function"><span class="keyword">function</span>(<span class="params">salary</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.salary = salary    <span class="comment">//设置员工的原始工资</span></span><br><span class="line">&#125;</span><br><span class="line">Bonus.prototype.setStrategy = <span class="function"><span class="keyword">function</span>(<span class="params">strategy</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.strategy = strategy</span><br><span class="line">&#125;</span><br><span class="line">Bonus.prototype.getBonus = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">this</span>.strategy.calculate(<span class="built_in">this</span>.salary)     <span class="comment">//把计算奖金的操作委托给对应的策略对象</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> bonus = <span class="keyword">new</span> Bonus(); </span><br><span class="line">bonus.setSalary( <span class="number">10000</span> ); </span><br><span class="line">bonus.setStrategy( <span class="keyword">new</span> performanceS() ); <span class="comment">// 设置策略对象</span></span><br><span class="line"><span class="built_in">console</span>.log( bonus.getBonus() ); <span class="comment">// 输出：40000 </span></span><br><span class="line">bonus.setStrategy( <span class="keyword">new</span> performanceA() ); <span class="comment">// 设置策略对象</span></span><br><span class="line"><span class="built_in">console</span>.log( bonus.getBonus() ); <span class="comment">// 输出：30000</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>JavaScript版本的策略模式</p>
  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">我们让 strategy 对象从各个策略类中创建而来，这是模拟一些传统面向对象语言的实现。实际上在 JavaScript 语言中，函数也是对象，所以更简单和直接的做法是把 strategy直接定义为函数：</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="comment">//策略对象</span></span><br><span class="line"><span class="keyword">var</span> strategies = &#123;</span><br><span class="line">    <span class="string">&quot;S&quot;</span>: <span class="function"><span class="keyword">function</span>(<span class="params"> salary </span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> salary*<span class="number">4</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="string">&quot;A&quot;</span>: <span class="function"><span class="keyword">function</span>(<span class="params"> salary </span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> salary*<span class="number">3</span></span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="string">&quot;B&quot;</span>: <span class="function"><span class="keyword">function</span>(<span class="params"> salary </span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> salary*<span class="number">2</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//操作类</span></span><br><span class="line"><span class="keyword">var</span> calculateBonus = <span class="function"><span class="keyword">function</span>(<span class="params">level,salary</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> strategies[level](salary)</span><br><span class="line">&#125;</span><br><span class="line">calculateBonus(<span class="string">&#x27;S&#x27;</span>,<span class="number">200</span>)  <span class="comment">//800</span></span><br></pre></td></tr></table></figure>
</li>
</ul>
</li>
</ul>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
    <article
  id="post-第四章__单例模式"
  class="article article-type-post"
  itemscope
  itemprop="blogPost"
  data-scroll-reveal
>
  <div class="article-inner">
    
    <header class="article-header">
       
<h2 itemprop="name">
  <a class="article-title" href="/2019/12/25/%E7%AC%AC%E5%9B%9B%E7%AB%A0__%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/"
    >【第四章】单例模式</a> 
</h2>
 

    </header>
     
    <div class="article-meta">
      <a href="/2019/12/25/%E7%AC%AC%E5%9B%9B%E7%AB%A0__%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F/" class="article-date">
  <time datetime="2019-12-25T02:21:42.000Z" itemprop="datePublished">2019-12-25</time>
</a> 
  <div class="article-category">
    <a class="article-category-link" href="/categories/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
  </div>
   
    </div>
      
    <div class="article-entry" itemprop="articleBody">
       
  <blockquote>
<p>定义： 保证一个类仅有一个实例，并提供一个访问它的全局访问点。在 JavaScript 开发中，单例模式的用途同样非常广泛。试想一下，当我们单击登录按钮的时候，页面中会出现一个登录浮窗，而这个登录浮窗是唯一的，无论单击多少次登录按钮，这个浮窗都只会被创建一次，那么这个登录浮窗就适合用单例模式来创建。</p>
</blockquote>
<p><b style="color:Red">核心：确保只有一个实例，并提供全局访问</b></p>
<ol>
<li><p>实现单例模式</p>
<blockquote>
<p>用一个变量来标志当前是否已经为某个类创建过对象，如果是，则在下一次获取该类的实例时，直接返回之前创建的对象</p>
  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Singleton = <span class="function"><span class="keyword">function</span>(<span class="params">name</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.name = name</span><br><span class="line">    <span class="built_in">this</span>.instance = <span class="literal">null</span>    <span class="comment">//存放已经生成的实例对象</span></span><br><span class="line">&#125;</span><br><span class="line">Singleton.prototype.getName = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="built_in">this</span>.name)</span><br><span class="line">&#125;</span><br><span class="line">Singleton.getInstance = <span class="function"><span class="keyword">function</span>(<span class="params">name</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(!<span class="built_in">this</span>.instance)&#123;</span><br><span class="line">        <span class="built_in">this</span>.instance = <span class="keyword">new</span> Singleton(name)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">this</span>.instance</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = Singleton.getInstance(<span class="string">&#x27;doreen&#x27;</span>)</span><br><span class="line"><span class="keyword">var</span> b = Singleton.getInstance(<span class="string">&#x27;sherry&#x27;</span>)</span><br><span class="line">a.getName()     <span class="comment">//doreen</span></span><br><span class="line">b.getName()     <span class="comment">//doreen</span></span><br><span class="line"><span class="built_in">console</span>.log(a === b)     <span class="comment">//true</span></span><br><span class="line"></span><br></pre></td></tr></table></figure></blockquote>
</li>
<li><p>透明的单例模式</p>
<blockquote>
<p>使用的时候要和普通类一样通过new去创建实例</p>
 <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 利用闭包的方式 让变量存在局部</span></span><br><span class="line"><span class="keyword">var</span> CreateDiv = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> instance </span><br><span class="line">    <span class="keyword">var</span> CreateDiv = <span class="function"><span class="keyword">function</span>(<span class="params">html</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(instance)&#123;</span><br><span class="line">            <span class="keyword">return</span> instance</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">this</span>.html = html</span><br><span class="line">        <span class="built_in">this</span>.init()</span><br><span class="line">        <span class="keyword">return</span> instance = <span class="built_in">this</span></span><br><span class="line">    &#125;</span><br><span class="line">    CreateDiv.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">var</span> div = <span class="built_in">document</span>.createElement(<span class="string">&#x27;div&#x27;</span>)</span><br><span class="line">        div.innerHTML = <span class="built_in">this</span>.html</span><br><span class="line">        <span class="built_in">document</span>.body.appendChild(div)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> CreateDiv;</span><br><span class="line">&#125;)()</span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> CreateDiv(<span class="string">&#x27;doreen&#x27;</span>)</span><br><span class="line"><span class="keyword">var</span> b = <span class="keyword">new</span> CreateDiv(<span class="string">&#x27;sherry&#x27;</span>)</span><br><span class="line"><span class="built_in">console</span>.log(a === b)    <span class="comment">// true</span></span><br><span class="line"></span><br></pre></td></tr></table></figure></blockquote>
</li>
<li><p>用代理实现单例模式</p>
<blockquote>
<p>CreateDiv变成普通类，它跟proxySingletonCreateDiv组合起来可以达到单例模式的效果</p>
</blockquote>
 <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> CreateDiv = <span class="function"><span class="keyword">function</span>(<span class="params">html</span>)</span>&#123;</span><br><span class="line">    <span class="built_in">this</span>.html = html</span><br><span class="line">    <span class="built_in">this</span>.init()</span><br><span class="line">&#125;</span><br><span class="line">CreateDiv.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> div = <span class="built_in">document</span>.createElement(<span class="string">&#x27;div&#x27;</span>)</span><br><span class="line">    div.innerHTML = <span class="built_in">this</span>.html</span><br><span class="line">    <span class="built_in">document</span>.body.appendChild(div)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//代理类 proxySingletonCreateDiv</span></span><br><span class="line"><span class="keyword">var</span> proxySingletonCreateDiv = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> instance</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">html</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!instance)&#123;</span><br><span class="line">            instance = <span class="keyword">new</span> CreateDiv(html)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> instance</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)()</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> proxySingletonCreateDiv(<span class="string">&#x27;doreen&#x27;</span>)</span><br><span class="line"><span class="keyword">var</span> b = <span class="keyword">new</span> proxySingletonCreateDiv(<span class="string">&#x27;sherry&#x27;</span>)</span><br><span class="line"><span class="built_in">console</span>.log(a===b)  <span class="comment">// true</span></span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
<li><p>惰性单例</p>
<blockquote>
<p>是在需要的时候才创建对象实例</p>
</blockquote>
 <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* 创建一个登录框  需要登录的时候才动态创建登录框*/</span></span><br><span class="line"><span class="keyword">var</span> createLoginLayer = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> div</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (!div) &#123;</span><br><span class="line">            div = <span class="built_in">document</span>.createElement(<span class="string">&#x27;div&#x27;</span>)</span><br><span class="line">            div.innerHTML = <span class="string">&#x27;登录框&#x27;</span></span><br><span class="line">            div.style.display = <span class="string">&#x27;none&#x27;</span></span><br><span class="line">            <span class="built_in">document</span>.body.appendChild(div)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> div</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)()</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> loginLayer = createLoginLayer()</span><br></pre></td></tr></table></figure></li>
<li><p>通用的惰性单例</p>
<blockquote>
<p>惰性单例存在的问题  </p>
<ol>
<li>违反单一职责原则，创建对象和管理单例的逻辑都放在createLoginLayer对象内部</li>
<li>如果下次需要创建页面中唯一的iframe，或者script标签，用来跨域请求数据，就必须如法炮制，把createLoginLayer函数几乎照抄一遍  <figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> createIframe = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> iframe</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(!iframe)&#123;</span><br><span class="line">            iframe = <span class="built_in">document</span>.createElement(<span class="string">&#x27;iframe&#x27;</span>)</span><br><span class="line">            iframe.style.display = <span class="string">&#x27;none&#x27;</span></span><br><span class="line">            <span class="built_in">document</span>.body.appendChild(iframe)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> iframe</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)()</span><br><span class="line"></span><br><span class="line"><span class="comment">//  把代码抽离出来</span></span><br><span class="line"><span class="comment">//  公用的部分 单例逻辑</span></span><br><span class="line"><span class="keyword">var</span> getSingle = <span class="function"><span class="keyword">function</span>(<span class="params">fn</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> result</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> result || (result = fn.apply(<span class="built_in">this</span>,<span class="built_in">arguments</span>))</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//  创建对象的方法</span></span><br><span class="line"><span class="keyword">var</span> createLoginLayer = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">var</span> div = <span class="built_in">document</span>.createElement(<span class="string">&#x27;div&#x27;</span>)</span><br><span class="line">    div.innerHTML = <span class="string">&#x27;登录框&#x27;</span></span><br><span class="line">    div.style.display = <span class="string">&#x27;none&#x27;</span></span><br><span class="line">    <span class="built_in">document</span>.body.appendChil(div)</span><br><span class="line">    <span class="keyword">return</span> div</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> createSingleLoginLayer = getSingle(createLoginLayer)</span><br></pre></td></tr></table></figure>
</li>
</ol>
</blockquote>
</li>
</ol>
 
      <!-- reward -->
      
    </div>
    

    <!-- copyright -->
    
    <footer class="article-footer">
       
    </footer>
  </div>

    
 
   
</article>

    
  </article>
  

  
  <nav class="page-nav">
    
    <a class="extend prev" rel="prev" href="/page/5/">上一页</a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/4/">4</a><a class="page-number" href="/page/5/">5</a><span class="page-number current">6</span><a class="page-number" href="/page/7/">7</a><a class="extend next" rel="next" href="/page/7/">下一页</a>
  </nav>
  
</section>
</div>

      <footer class="footer">
  <div class="outer">
    <ul>
      <li>
        Copyrights &copy;
        2019-2023
        <i class="ri-heart-fill heart_icon"></i> John Doe
      </li>
    </ul>
    <ul>
      <li>
        
      </li>
    </ul>
    <ul>
      <li>
        
        
        <span>
  <span><i class="ri-user-3-fill"></i>Visitors:<span id="busuanzi_value_site_uv"></span></s>
  <span class="division">|</span>
  <span><i class="ri-eye-fill"></i>Views:<span id="busuanzi_value_page_pv"></span></span>
</span>
        
      </li>
    </ul>
    <ul>
      
    </ul>
    <ul>
      
    </ul>
    <ul>
      <li>
        <!-- cnzz统计 -->
        
      </li>
    </ul>
  </div>
</footer>
      <div class="float_btns">
        <div class="totop" id="totop">
  <i class="ri-arrow-up-line"></i>
</div>

<div class="todark" id="todark">
  <i class="ri-moon-line"></i>
</div>

      </div>
    </main>
    <aside class="sidebar on">
      <button class="navbar-toggle"></button>
<nav class="navbar">
  
  <div class="logo">
    <a href="/"><img src="/images/avatar.webp" alt="Doreen&#39;s Blog"></a>
  </div>
  
  <ul class="nav nav-main">
    
    <li class="nav-item">
      <a class="nav-item-link" href="/">主页</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/categories">分类</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/archives">归档</a>
    </li>
    
    <li class="nav-item">
      <a class="nav-item-link" href="/about">关于我</a>
    </li>
    
  </ul>
</nav>
<nav class="navbar navbar-bottom">
  <ul class="nav">
    <li class="nav-item">
      
      <a class="nav-item-link nav-item-search"  title="Search">
        <i class="ri-search-line"></i>
      </a>
      
      
    </li>
  </ul>
</nav>
<div class="search-form-wrap">
  <div class="local-search local-search-plugin">
  <input type="search" id="local-search-input" class="local-search-input" placeholder="Search...">
  <div id="local-search-result" class="local-search-result"></div>
</div>
</div>
    </aside>
    <script>
      if (window.matchMedia("(max-width: 768px)").matches) {
        document.querySelector('.content').classList.remove('on');
        document.querySelector('.sidebar').classList.remove('on');
      }
    </script>
    <div id="mask"></div>

<!-- #reward -->
<div id="reward">
  <span class="close"><i class="ri-close-line"></i></span>
  <p class="reward-p"><i class="ri-cup-line"></i>请我喝杯咖啡吧~</p>
  <div class="reward-box">
    
    <div class="reward-item">
      <img class="reward-img" src="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/img/alipay.jpg">
      <span class="reward-type">支付宝</span>
    </div>
    
    
    <div class="reward-item">
      <img class="reward-img" src="https://cdn.jsdelivr.net/gh/Shen-Yu/cdn/img/wechat.jpg">
      <span class="reward-type">微信</span>
    </div>
    
  </div>
</div>
    
<script src="/js/jquery-2.0.3.min.js"></script>


<script src="/js/lazyload.min.js"></script>

<!-- Tocbot -->

<script src="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/jquery-modal@0.9.2/jquery.modal.min.css">
<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.7.0/dist/js/jquery.justifiedGallery.min.js"></script>

<script src="/dist/main.js"></script>

<!-- ImageViewer -->

<!-- Root element of PhotoSwipe. Must have class pswp. -->
<div class="pswp" tabindex="-1" role="dialog" aria-hidden="true">

    <!-- Background of PhotoSwipe. 
         It's a separate element as animating opacity is faster than rgba(). -->
    <div class="pswp__bg"></div>

    <!-- Slides wrapper with overflow:hidden. -->
    <div class="pswp__scroll-wrap">

        <!-- Container that holds slides. 
            PhotoSwipe keeps only 3 of them in the DOM to save memory.
            Don't modify these 3 pswp__item elements, data is added later on. -->
        <div class="pswp__container">
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
            <div class="pswp__item"></div>
        </div>

        <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->
        <div class="pswp__ui pswp__ui--hidden">

            <div class="pswp__top-bar">

                <!--  Controls are self-explanatory. Order can be changed. -->

                <div class="pswp__counter"></div>

                <button class="pswp__button pswp__button--close" title="Close (Esc)"></button>

                <button class="pswp__button pswp__button--share" style="display:none" title="Share"></button>

                <button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>

                <button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>

                <!-- Preloader demo http://codepen.io/dimsemenov/pen/yyBWoR -->
                <!-- element will get class pswp__preloader--active when preloader is running -->
                <div class="pswp__preloader">
                    <div class="pswp__preloader__icn">
                        <div class="pswp__preloader__cut">
                            <div class="pswp__preloader__donut"></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
                <div class="pswp__share-tooltip"></div>
            </div>

            <button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
            </button>

            <button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
            </button>

            <div class="pswp__caption">
                <div class="pswp__caption__center"></div>
            </div>

        </div>

    </div>

</div>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.min.css">
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js"></script>

<script>
    function viewer_init() {
        let pswpElement = document.querySelectorAll('.pswp')[0];
        let $imgArr = document.querySelectorAll(('.article-entry img:not(.reward-img)'))

        $imgArr.forEach(($em, i) => {
            $em.onclick = () => {
                // slider展开状态
                // todo: 这样不好，后面改成状态
                if (document.querySelector('.left-col.show')) return
                let items = []
                $imgArr.forEach(($em2, i2) => {
                    let img = $em2.getAttribute('data-idx', i2)
                    let src = $em2.getAttribute('data-target') || $em2.getAttribute('src')
                    let title = $em2.getAttribute('alt')
                    // 获得原图尺寸
                    const image = new Image()
                    image.src = src
                    items.push({
                        src: src,
                        w: image.width || $em2.width,
                        h: image.height || $em2.height,
                        title: title
                    })
                })
                var gallery = new PhotoSwipe(pswpElement, PhotoSwipeUI_Default, items, {
                    index: parseInt(i)
                });
                gallery.init()
            }
        })
    }
    viewer_init()
</script>

<!-- MathJax -->

<!-- Katex -->

<!-- busuanzi  -->


<script src="/js/busuanzi-2.3.pure.min.js"></script>


<!-- ClickLove -->

<!-- ClickBoom1 -->

<!-- ClickBoom2 -->


<script src="/js/clickBoom2.js"></script>


<!-- CodeCopy -->


<link rel="stylesheet" href="/css/clipboard.css">

<script src="https://cdn.jsdelivr.net/npm/clipboard@2/dist/clipboard.min.js"></script>
<script>
  function wait(callback, seconds) {
    var timelag = null;
    timelag = window.setTimeout(callback, seconds);
  }
  !function (e, t, a) {
    var initCopyCode = function(){
      var copyHtml = '';
      copyHtml += '<button class="btn-copy" data-clipboard-snippet="">';
      copyHtml += '<i class="ri-file-copy-2-line"></i><span>COPY</span>';
      copyHtml += '</button>';
      $(".highlight .code pre").before(copyHtml);
      $(".article pre code").before(copyHtml);
      var clipboard = new ClipboardJS('.btn-copy', {
        target: function(trigger) {
          return trigger.nextElementSibling;
        }
      });
      clipboard.on('success', function(e) {
        let $btn = $(e.trigger);
        $btn.addClass('copied');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-checkbox-circle-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPIED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-checkbox-circle-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
      clipboard.on('error', function(e) {
        e.clearSelection();
        let $btn = $(e.trigger);
        $btn.addClass('copy-failed');
        let $icon = $($btn.find('i'));
        $icon.removeClass('ri-file-copy-2-line');
        $icon.addClass('ri-time-line');
        let $span = $($btn.find('span'));
        $span[0].innerText = 'COPY FAILED';
        
        wait(function () { // 等待两秒钟后恢复
          $icon.removeClass('ri-time-line');
          $icon.addClass('ri-file-copy-2-line');
          $span[0].innerText = 'COPY';
        }, 2000);
      });
    }
    initCopyCode();
  }(window, document);
</script>


<!-- CanvasBackground -->


<script src="/js/dz.js"></script>



    
  </div>
</body>

</html>